import json
import logging
import time
import traceback
from datetime import datetime
from pythonping import ping
from django.db import transaction
from django.views import View
from django.http import JsonResponse
from rest_framework.status import HTTP_200_OK, HTTP_400_BAD_REQUEST
from onu.models import OltInfo, BoardInfo
from onu.modelsView import OltView
from mgtServer.settings import GLOBALTlenetObj
from tools.Tools import createHandleLog, getCurrentUser, getSourceLen, getDataPaging
from tools.autoregister.autoregister import telnetip as HuaWeiClient
from tools.autoregister.zte_autoregister import telnetip as ZTEClient

logger_info = logging.getLogger('info')
res = dict()


class HostView(View):
    res.clear()

    def get(self, request, *args, **kwargs):
        try:
            current = request.GET.get("current")
            pageSize = request.GET.get("pageSize")
            olt_name = request.GET.get("olt_name")
            dataInfo = OltView.objects.all()
            if olt_name is not None and olt_name != '':
                dataInfo = dataInfo.filter(olt_info=olt_name)
            total = getSourceLen(dataInfo)
            data = getDataPaging(dataInfo, int(pageSize), int(current))
            for i in data:
                status = ping(target=i['olt_ip'], count=1, timeout=0.1).success()
                OltInfo.objects.filter(olt_ip=i['olt_ip']).update(host_status='正常' if status else '宕机')
            res['status'] = 200
            res['data'] = data
            res['total'] = total
            res['current'] = current
            res['pageSize'] = pageSize
            res['messages'] = '请求成功'
            return JsonResponse(res, status=HTTP_200_OK)
        except:
            logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}\n\n')
            res['status'] = 400
            res['message'] = '请求错误'
            return JsonResponse(res, status=HTTP_400_BAD_REQUEST)

    @transaction.atomic
    def post(self, request, *args, **kwargs):
        try:
            body = json.loads(request.body)
            status, message = createHost(body)
            createHandleLog('新增主机', str(getCurrentUser(request)), body)
            logger_info.info(f'{getCurrentUser(request)} 在 {str(datetime.now())[:19]} 操作《新增主机》权限 新增内容 {body}')
            res['status'] = status
            res['message'] = message
            return JsonResponse(res, status=HTTP_200_OK)
        except:
            logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}\n\n')
            res['status'] = 400
            res['message'] = '请求错误'
            return JsonResponse(res, status=HTTP_400_BAD_REQUEST)

    @transaction.atomic
    def put(self, request, *args, **kwargs):
        try:
            body = json.loads(request.body)
            oltId = body.get('oltId')
            olt_name = body.get('olt_name')
            olt_system_name = body.get('olt_system_name')
            up_port = body.get('up_port')
            line_template_gpon = body.get('line_template_gpon')
            line_template_epon = body.get('line_template_epon')
            business_template_epon = body.get('business_template_epon')
            business_template_gpon = body.get('business_template_gpon')
            business_outer = body.get('business_outer')
            business_intimal = body.get('business_intimal')
            OltInfo.objects.filter(olt_id=oltId).update(olt_name=olt_name, olt_system_name=olt_system_name,
                                                        up_port=up_port)
            BoardInfo.objects.filter(olt_info_id=oltId).update(line_template_gpon=line_template_gpon,
                                                               line_template_epon=line_template_epon,
                                                               business_template_epon=business_template_epon,
                                                               business_template_gpon=business_template_gpon,
                                                               business_outer=business_outer,
                                                               business_intimal=business_intimal,
                                                               modified_time=datetime.now()
                                                               )
            createHandleLog('修改主机', str(getCurrentUser(request)), body)
            logger_info.info(f'{getCurrentUser(request)} 在 {str(datetime.now())[:19]} 操作《修改主机》权限 修改内容 {body}')

            res['status'] = 200
            res['message'] = '修改成功'
            return JsonResponse(res, status=HTTP_200_OK)
        except:
            logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}\n\n')
            res['status'] = 400
            res['message'] = '请求错误'
            return JsonResponse(res, status=HTTP_400_BAD_REQUEST)

    @transaction.atomic
    def delete(self, request, *args, **kwargs):
        try:
            oltId = request.GET.get("oltId")
            data = OltInfo.objects.get(olt_id=oltId)
            data.delete()
            BoardInfo.objects.filter(olt_info_id=oltId).delete()
            createHandleLog('删除主机', str(getCurrentUser(request)), "主机名称：%s" % data.olt_name)
            logger_info.info(
                f'{getCurrentUser(request)} 在 {str(datetime.now())[:19]} 操作《删除主机》权限  操作内容 {data.olt_name}')
            res['status'] = 200
            res['message'] = '删除成功'
            return JsonResponse(res, status=HTTP_200_OK)
        except:
            logger_info.error(f'当前接口：{request.path} 异常，异常内容为:{traceback.format_exc()}\n\n')
            res['status'] = 400
            res['message'] = '请求错误'
            return JsonResponse(res, status=HTTP_400_BAD_REQUEST)


# 获取OLT 连接对象
def getOltConnect(ip):
    olt_info = OltInfo.objects.get(olt_ip=ip)
    try:
        olt_time = GLOBALTlenetObj[ip]['time']
        current = int(time.time())
        if current - olt_time < 1800:
            return GLOBALTlenetObj[ip]['connect']
        else:
            del GLOBALTlenetObj[ip]
            if olt_info.olt_mode == '华为':
                client = HuaWeiClient(olt_info.olt_ip, olt_info.olt_port, olt_info.olt_account, olt_info.olt_passwd)
                client.login_host()
                client.base_config(1)
                GLOBALTlenetObj[ip] = {'connect': client, 'time': int(time.time())}
            else:
                client = ZTEClient(olt_info.olt_ip, olt_info.olt_port, olt_info.olt_account, olt_info.olt_passwd)
                client.login_host()
                client.base_config(1)
                GLOBALTlenetObj[ip] = {'connect': client, 'time': int(time.time())}
            return client
    except:

        if olt_info.olt_mode == '华为':
            client = HuaWeiClient(olt_info.olt_ip, olt_info.olt_port, olt_info.olt_account, olt_info.olt_passwd)
            client.login_host()
            client.base_config(1)
            GLOBALTlenetObj[ip] = {'connect': client, 'time': int(time.time())}
        else:
            client = ZTEClient(olt_info.olt_ip, olt_info.olt_port, olt_info.olt_account, olt_info.olt_passwd)
            client.login_host()
            client.base_config(1)
            GLOBALTlenetObj[ip] = {'connect': client, 'time': int(time.time())}
        return client


@transaction.atomic
def createHost(data: dict):
    """
    :param data 添加olt 数据
    """
    olt_name = data.get('olt_name')
    olt_system_name = data.get('olt_system_name')
    olt_mode = data.get('olt_mode')
    olt_ip = data.get('olt_ip')
    olt_port = data.get('olt_port')
    olt_account = data.get('olt_account')
    olt_passwd = data.get('olt_passwd')
    up_port = data.get('up_port')
    line_template_gpon = int(data.get('line_template_gpon'))
    business_template_gpon = int(data.get('business_template_gpon'))
    line_template_epon = int(data.get('line_template_epon'))
    business_template_epon = int(data.get('business_template_epon'))
    business_outer = int(data.get('business_outer'))
    business_intimal = int(data.get('business_intimal'))
    save_mode = data.get('save_mode')
    save_hours = int(data.get('save_hours'))
    gemport = int(data.get('gemport'))
    if not OltInfo.objects.filter(olt_ip=olt_ip).exists():
        createData = OltInfo.objects.create()
        createData.olt_id = createData.id
        createData.olt_name = olt_name
        createData.olt_system_name = olt_system_name
        createData.olt_ip = olt_ip
        createData.olt_port = olt_port
        createData.olt_account = olt_account
        createData.olt_passwd = olt_passwd
        createData.up_port = up_port
        createData.up_down_remind = "True"
        createData.save_hours = save_hours
        createData.save_mode = save_mode
        status = ping(target=olt_ip, count=1, timeout=0.1).success()
        createData.host_status = '正常' if status else '宕机'
        createData.olt_mode = olt_mode
        createData.save()
        BoardInfo.objects.create(line_template_gpon=line_template_gpon,
                                 business_template_gpon=business_template_gpon,
                                 line_template_epon=line_template_epon,
                                 business_template_epon=business_template_epon,
                                 business_intimal=business_intimal,
                                 business_outer=business_outer,
                                 gemport=gemport,
                                 default_data="Y",
                                 run_mode="full-automatic",
                                 filtration="false",
                                 olt_info_id=createData.olt_id,
                                 created_time=datetime.now())
        client = getOltConnect(olt_ip)
        all_port_list = list()
        # 获取板卡信息
        board_result, status = client.board_info(scope="usable", userrole="user")
        # 获取板口信息
        if board_result:
            for board in board_result:
                info = dict()
                if olt_mode == '华为':
                    port_result = client.board_one(board[0], scope="port_num", userrole="user")
                    info["slotid"] = board[0]
                    info["port_num_list"] = port_result
                else:
                    info["slotid"] = board[2]
                    port_result = []
                    for j in range(1, int(board[5]) + 1):
                        port_result.append(j)
                    info["port_num_list"] = port_result
                if port_result:
                    all_port_list.append(info)
                    createBoardPort(createData.olt_id, gemport, board[0], port_result, line_template_gpon,
                                    business_template_gpon, line_template_epon, business_template_epon,
                                    business_intimal, business_outer)
            print(all_port_list)
        return 200, '添加成功'
    else:
        return 400, '不能添加已有设备'


@transaction.atomic
def createBoardPort(oltId: int, gemport: int, slotid: int, port_list: list, line_gpon: int, business_gpon: int,
                    line_epon: int, business_epon: int, intimal: int, outer: int):
    """
    :param oltId 设备Id
    :param gemport gemport
    :param slotid 板卡
    :param port_list 板口信息
    :param line_gpon GPON 线路模板
    :param line_epon EPON 线路模板
    :param business_gpon GPON 业务模板
    :param business_epon EPON 业务模板
    :param intimal 业务内层模板
    :param outer 业务外层模板
    """
    for port in port_list:
        createData = BoardInfo.objects.create()
        createData.frameid = 0
        createData.slotid = slotid
        createData.board_port = port
        createData.line_template_gpon = line_gpon
        createData.business_template_gpon = business_gpon
        createData.line_template_epon = line_epon
        createData.business_template_epon = business_epon
        createData.business_intimal = intimal
        createData.business_outer = outer
        createData.gemport = gemport
        createData.run_mode = "full-automatic"
        createData.filtration = "false"
        createData.olt_info_id = oltId
        createData.created_time = datetime.now()
        createData.save()
    return True
